<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Framework
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-07-20
 ***********************************************************************/
if(defined("IVANENGINE_FRAMEWORK_ROUTING_PATTERN"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_FRAMEWORK_ROUTING_PATTERN", true);

require_once (dirname(__FILE__).'/../Common.php');
require_once (M_CORE_PATH.'Routing/Routing.php');

class CPatternRouting extends CRouting
{
    protected $m_routs  = null;
    public function __construct()
    {
        parent::__construct();
        $this->m_routes = new CMap();
    }

    public function __destruct()
    {
        unset($this->m_routes);
        parent::__destruct();
    }
    
    public function GetCurUri()
    {
        $parameters = $_GET;
        $action = sprintf('%s/%s', $parameters['plugin'], $parameters['action']);

        // other parameters
        unset($parameters['plugin'], $parameters['action']);
        ksort($parameters);
        $parameters = count($parameters) ? '?'.http_build_query($parameters, null, '&') : '';

        return sprintf('%s%s', $action, $parameters);
    }
    
    public function Generate($name, $parameters, $absolute)
    {
        if ($name)
        {
            // named route
            if ( !$this->HasKey($name) )
            {
                throw new CException404Error(
                    sprintf('The route "%s" does not exist.', $name));
            }

            $route = $this->Get($name);

            if (is_string($route))
            {
                $route = $this->_LoadRoute($name);
            }
        }else{
            // find a matching route
            if (false === $route = $this->_GetRouteThatMatchesParam($params, $this->m_options[self::OT_Context]))
            {
                throw new CException404Error(
                    sprintf('Unable to find a matching route to generate url for params "%s".', 
                        is_object($parameters) ? 
                        'Object('.get_class($parameters).')' : 
                        str_replace("\n", '', var_export($parameters, true))));
            }
        }

        $url = $route->Generate($parameters, $this->m_options[self::OT_Context], $absolute);
    }
    
    protected function _LoadRoute($name)
    {
        if (is_string($route = $this->m_routes->Get($name)))
        {
            $this->m_routes->Set($name, unserialize($route));
            return $this->m_routes->Get($name);
        }
        else
        {
            return $route;
        }
    }
    
    protected function _GetRouteThatMatchesParam($parameters)
    {
        foreach ($this->m_routes as $name => $route)
        {
            if (is_string($route))
            {
                $route = $this->_LoadRoute($name);
            }

            if ($route->IsMatchesParam($parameters, $this->m_options[self::OT_Context]))
            {
                return $route;
            }
        }
        return false;
    }
}
?>
